package com.example.everying.service.user.impl;/*
 * 项目名称: everything
 * 文件名: UserScoreServiceImpl
 * 作者: 张泽阳
 * 日期: 2025/6/25
 * 描述:
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.CacheConstants;
import com.example.everying.context.UserContext;
import com.example.everying.mapper.user.UserScoreMapper;
import com.example.everying.model.entity.user.UserEntity;
import com.example.everying.model.entity.user.UserScore;
import com.example.everying.model.vo.user.LoginUser;
import com.example.everying.model.vo.user.UserInfoVo;
import com.example.everying.service.user.UserScoreService;
import com.example.everying.service.user.UserService;
import com.example.everying.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@Slf4j
public class UserScoreServiceImpl extends ServiceImpl<UserScoreMapper, UserScore> implements UserScoreService {
    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCreditWeight(String userId, Double creditWeight) {
        log.info("userId:{},creditWeight:{}", userId, creditWeight);
        UserScore userScore = getUserById(userId);
        if (userScore.getCommentAverage() + creditWeight >= 5.0){
            return true;
        }
        userScore.setUpdateTime(LocalDateTime.now());
        userScore.setCreditWeight(creditWeight);
        userScore.setCreditValue(userScore.getCommentAverage() + creditWeight);
        boolean flag = updateById(userScore);
        boolean userFlag = false;
        if (flag){
            UserEntity user = userService.getById(userId);
            user.setCreditValue(userScore.getCreditValue());
            userFlag = userService.updateById(user);
            if (userFlag){
                updateCacheAndContext(userId, userScore.getCreditValue());
            }
        }
        return userFlag;
    }

    @Override
    public boolean updateCommentAverage(String userId, Double commentAverage) {
        UserScore userScore = getUserById(userId);
        if (commentAverage + userScore.getCreditWeight() >= 5.0){
            return true;
        }
        userScore.setUpdateTime(LocalDateTime.now());
        userScore.setCommentAverage(commentAverage);
        userScore.setCreditValue(commentAverage + userScore.getCreditWeight());
        boolean flag = updateById(userScore);
        boolean userFlag = false;
        if (flag){
            UserEntity user = userService.getById(userId);
            user.setCreditValue(userScore.getCreditValue());
            userFlag = userService.updateById(user);
            if (userFlag){
                updateCacheAndContext(userId, user.getCreditValue());
            }
        }
        return userFlag;
    }

    @Override
    public boolean updateMonthlyCreditIncrement(String userId, Double monthlyCreditIncrement) {
        log.info("userId:{},monthlyCreditIncrement:{}", userId, monthlyCreditIncrement);
        UserScore userScore = getUserById(userId);
        if (userScore.getCreditValue() + monthlyCreditIncrement >= 5.0 ){
            return true;
        }
        if (userScore.getMonthlyCreditIncrement() != null && userScore.getMonthlyCreditIncrement() > 1.0){
            return true;
        }

        int currentMonth = LocalDateTime.now().getMonth().getValue();
        // 如果月份更新加权清零
        if (userScore.getMonthlyCreditIncrement() != null && userScore.getLastCreditUpdateMonth() != currentMonth){
            userScore.setMonthlyCreditIncrement(0.0);
            userScore.setLastCreditUpdateMonth(currentMonth);
        }
        userScore.setCreditWeight(userScore.getCreditWeight() + monthlyCreditIncrement);
        userScore.setMonthlyCreditIncrement(userScore.getMonthlyCreditIncrement() + monthlyCreditIncrement);
        userScore.setCreditValue(userScore.getCommentAverage() + userScore.getCreditWeight());

        userScore.setUpdateTime(LocalDateTime.now());

        boolean flag = updateById(userScore);
        boolean userFlag = false;
        if ( flag){
            UserEntity user = userService.getById(userId);
            user.setCreditValue(userScore.getCreditValue());
            userFlag = userService.updateById(user);
            if (userFlag){
                updateCacheAndContext(userId, userScore.getCreditValue());
            }
        }
        return userFlag;
    }

    public UserScore getUserById(String userId){
        LambdaQueryWrapper<UserScore> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserScore::getUserId, userId);
        return getOne(queryWrapper);
    }

    public void updateCacheAndContext(String userId, Double creditValue){
        UserInfoVo user = UserContext.getUser();
        user.setCreditValue(creditValue);
        UserContext.setUser(user);

        LoginUser userinfo = redisUtils.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + userId);
        userinfo.setCreditValue(creditValue);
        redisUtils.setCacheObject(CacheConstants.LOGIN_TOKEN_KEY + userId, userinfo);

    }
}
